<template>
  <div>
    <!-- 表格组件，绑定数据源和配置选项 -->
    <el-table ref="dataTable" :data="dataSource.list || []" :height="tableHeight" :stripe="options.stripe"
      :border="options.border" header-row-class-name="table-header-row" highlight-current-row
      @row-click="handleRowClick" @selection-change="handleSelectionChange">
      <!-- 选择框列，当 options.selectType 为 'checkbox' 时显示 -->
      <el-table-column v-if="options.selectType && options.selectType === 'checkbox'" type="selection" width="50"
        align="center"></el-table-column>

      <!-- 序号列，当 options.showIndex 为 true 时显示 -->
      <el-table-column v-if="options.showIndex" label="序号" type="index" width="60" align="center"></el-table-column>

      <!-- 数据列，通过 v-for 循环渲染 -->
      <template v-for="(column, index) in columns">
        <template v-if="column.scopedSlots">
          <!-- 使用作用域插槽的列 -->
          <el-table-column :key="index" :prop="column.prop" :label="column.label" :align="column.align || 'left'"
            :width="column.width">
            <template #default="scope">
              <!-- 插槽内容，通过 scope 访问当前行的数据 -->
              <slot :name="column.scopedSlots" :index="scope.$index" :row="scope.row"></slot>
            </template>
          </el-table-column>
        </template>
        <template v-else>
          <!-- 普通列 -->
          <el-table-column :key="index" :prop="column.prop" :label="column.label" :align="column.align || 'left'"
            :width="column.width" :fixed="column.fixed"></el-table-column>
        </template>
      </template>
    </el-table>

    <!-- 分页组件，当 showPagination 为 true 时显示 -->
    <div class="pagination" v-if="showPagination">
      <el-pagination v-if="dataSource.totalCount" background :total="dataSource.totalCount"
        :page-sizes="[15, 30, 50, 100]" :page-size="dataSource.pageSize" :current-page.sync="dataSource.pageNo"
        layout="total,sizes,prev, pager,next, jumper" @size-change="handlePageSizeChange"
        @current-change="handlePageNoChange" style="text-align:right"></el-pagination>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';

// 定义组件发出的事件  
const emit = defineEmits(['rowSelected', 'rowClick']);

// 定义组件接收的 props  
const props = defineProps({
  dataSource: Object, // 数据源对象，包含列表、总记录数、每页显示个数等  
  showPagination: {
    type: Boolean,
    default: true, // 是否显示分页组件  
  },
  options: {
    type: Object,
    default: {
      exHeight: 0, // 额外高度，用于计算表格高度  
      showIndex: false, // 是否显示序号列  
      stripe: false, // 是否显示斑马线  
      border: true, // 是否显示边框  
      // 可以根据需要添加更多选项  
    },
  },
  columns: Array, // 表格列配置数组  
  fetch: Function, // 获取数据的函数  
  initFetch: {
    type: Boolean,
    default: true, // 是否在初始化时自动获取数据  
  },
});

// 当前选中的行索引（虽然这里定义了，但在代码中未使用）  
const radioSelectRowIndex = ref(null);

// 表格高度的计算值  
const toHeight = 60 + 20 + 30 + 46 ; // 这里的数值可能需要根据实际布局调整  
const tableHeight = ref(
  props.options.tableHeight // 如果传入了 tableHeight，则使用传入的值  
    ? props.options.tableHeight
    : window.innerHeight - toHeight - (props.options.exHeight || 0) // 否则计算高度，并考虑 exHeight  
);

// 对 el-table 的引用  
const dataTable = ref();

// 行点击事件处理函数  
const handleRowClick = (row) => {
  emit("rowClick", row); // 发出行点击事件，传递当前行数据  
};

// 选择变化事件处理函数  
const handleSelectionChange = (selection) => {
  emit("rowSelected", selection); // 发出选择变化事件，传递当前选中的行（可能是一个数组）  
};

// 每页显示个数改变时的处理函数  
const handlePageSizeChange = (size) => {
  // 注意：直接修改 props 是不推荐的做法，应通过事件或回调函数通知父组件更新  
  props.dataSource.pageSize = size;
  props.dataSource.pageNo = 1; // 重置页码为第一页  
  props.fetch(); // 重新获取数据  
};

// 当前页码改变时的处理函数  
const handlePageNoChange = (pageNo) => {
  // 注意：同样，直接修改 props 是不推荐的做法  
  props.dataSource.pageNo = pageNo;
  props.fetch(); // 重新获取数据  
};

// 设置当前行的函数（通过 rowKey 和 rowValue 查找并设置）  
const setCurrentRow = (rowKey, rowValue) => {
  const row = props.dataSource.list.find((item) => item[rowKey] === rowValue);
  if (row) {
    dataTable.value.setCurrentRow(row); // 设置当前行  
  }
};

// 暴露 setCurrentRow 方法，以便父组件调用  
defineExpose({
  setCurrentRow,
});

// 初始化函数，根据 initFetch 和 fetch prop 决定是否自动获取数据  
const init = () => {
  if (props.initFetch && props.fetch) {
    props.fetch();
  }
};

// 执行初始化  
init();  
</script>

<style lang="scss">
.pagination {
  padding-top: 10px; // 分页组件上方的内边距  
}

.el-pagination {
  justify-content: right; // 分页组件内的内容右对齐  
}

/* 高亮当前行和悬停行的样式 */
.el-table__body tr.current-row>td.el-table__cell {
  background-color: #e6f0f9;
}

.el-table__body tr:hover>td.el-table__cell {
  background-color: #e6f0f9 !important; // 使用 !important 确保样式覆盖组件库的默认样式  
}
</style>